#ifndef GRIDFRAME_H
#define GRIDFRAME_H

/**
 * \file GridFrame.h
 * \brief Fichier contenant la déclaration de la classe GridFrame.
 */


#include "PointCloud.h"

class GridFrame
{
	/* \class GridFrame
	 * \brief Une GrdiFrame est une case d'une XYGrid. Elle est définie par deux points et le nuage de points qu'elle contient.
	 */
	private :

	Point bot;			/*!<Coin inferieur gauche d'une case de grille*/
	Point top;			/*!<Coin superieur droit d'une case de grille*/
	PointCloud cloud;	/*!<Nuage de points contenu dans cette case*/

	public :

	/*!
     *  \brief Constructeur de la classe GridFrame
     *
     *  Constructeur de la classe GridFrame
     */
	GridFrame();
	
	/*!
     *  \brief Constructeur de la classe GridFrame
	 *
     *  Constructeur de la classe GridFrame
	 *
	 *  \param _bot : Coin inferieur gauche définissant la case. Sa hauteur n'est pas à prendre en compte.
	 *  \param _top : Coin superieur droit définissant la case. Sa hauteur n'est pas à prendre en compte.
     */
	GridFrame(Point _bot, Point _top);

	/*!
     *  \brief Constructeur de la classe GridFrame
	 *
     *  Constructeur de la classe GridFrame
	 *
	 *  \param _bot : Coin inferieur gauche définissant la case. Sa hauteur n'est pas à prendre en compte.
	 *  \param _top : Coin superieur droit définissant la case. Sa hauteur n'est pas à prendre en compte.
	 *	\param _cloud : Nuage de points que contient la case.
     */
	GridFrame(Point _bot, Point _top, PointCloud _cloud);
	
	/*!
     *  \brief Renvoie la taille du nuage de points contenu dans la case
	 *
     *  Renvoie la taille du nuage de points contenu dans la case
	 *
	 *  \return : Renvoie la taille du nuage de points contenu dans la case.
     */
	int getSizeOfCloud ();
	
	/*!
     *  \brief Renvoie le point inferieur gauche de la case.
	 *
     *  Renvoie le point inferieur gauche de la case.
	 *
	 *  \return : Renvoie le point inferieur gauche de la case.
     */
	Point getBotPoint ();
	
	/*!
     *  \brief Renvoie le point superieur droit de la case.
	 *
     *  Renvoie le point superieur droit de la case.
	 *
	 *  \return : Renvoie le point superieur droit de la case.
     */
	Point getTopPoint ();
	
	/*!
     *  \brief Modificateur de la classe GridFrame
	 *
     *  Modificateur de la classe GridFrame
	 *
	 *  \param _p : Le point _p sera affecté à l'attribut bot de l'objet.
	 *  \return : void
     */
	void setPointBot ( Point _p );
	
	/*!
     *  \brief Modificateur de la classe GridFrame
	 *
     *  Modificateur de la classe GridFrame
	 *
	 *  \param _p : Le point _p sera affecté à l'attribut top de l'objet.
	 *  \return : void
     */
	void setPointTop ( Point _p );
	
	/*!
	*  \brief Accede à la hauteur minimale du nuage de points de la case.
	*
	*  Accede à la hauteur minimale du nuage de points de la case.
	*
	* \return : Renvoie la hauteur minimale du nuage de points de la case.
	*/
	float getZMin ();
	
	/*!
	*  \brief Accede au point de hauteur minimale du nuage de points de la case.
	*
	*  Accede au point de hauteur minimale du nuage de points de la case.
	*
	* \return : Renvoie la point de hauteur minimale du nuage de points de la case.
	*/
	Point getPointMin ();
	
	/*!
     *  \brief Ajoute un point au nuage de point de la case
	 *
     *  Ajoute un point au nuage de point de la case
	 *
	 *  \param _p : Point à ajouter au nuage de points.
	 *  \return : void
     */
	void addPointToCloud ( Point _p );
	
	/*!
     *  \brief Affiche les bordures de la case de la grille à une hauteur souhaitée.
	 *
     *  Affiche les bordures de la case de la grille à la hauteur _z.
	 *  \param _z : hauteur à laquelle on souhaite afficher la case.
	 *  \return : void
     */
	void displayFrame ( float _z = 0.0);
	
	/*!
     *  \brief Affiche la case de la grille comme un carré de couleur.
	 *
     *  Affiche la case de la grille comme un carré de couleur.
	 *
	 *  \return : void
     */
	void displayFrameColor ();
	
	/*!
     *  \brief Affiche la case de la grille comme un carré de couleur à une hauteur souhaitée.
	 *
     *  Affiche la case de la grille comme un carré de couleur à la hauteur _z.
	 *  \param _z : hauteur à laquelle on souhaite afficher la case.
	 *  \param _r : intensite de niveau de rouge de la couleur a afficher.
	 *  \param _g : intensite de niveau de vert de la couleur a afficher.
	 *  \param _b : intensite de niveau de bleu de la couleur a afficher.
	 *  \return : void
     */
	void displayFrameColor ( float _z, float _r, float _g, float _b );
	
	/*!
     *  \brief Affiche le nuage de points contenu dans la case.
	 *
     *  Affiche le nuage de points contenu dans la case.
	 *
	 *  \return : void
     */
	void displayCloud ();
	
	/*!
     *  \brief Affiche le nuage de points contenu dans la case en couleur.
	 *
     *  Affiche le nuage de points contenu dans la case en couleur.
	 *
	 *  \return : void
     */
	void displayCloud ( float _r, float _g, float _b);
	
	/*!
     *  \brief Affiche le nuage de points contenu dans la case et les bordures de la case.
	 *
     *  Affiche le nuage de points contenu dans la case et les bordures de la case.
	 *
	 *  \return : void
     */
	void display ();
	
	/*!
     *  \brief Seuille le nuage de points selon la hauteur de ceux ci.
	 *
     *  Seuille le nuage de points selon la hauteur de ceux ci.
	 *
	 *  \param _zMin : seuil bas de hauteur.
	 *  \param _zMax : seuil haut de hauteur.
	 *
	 *  \return : void
     */
	void keepPointsBetween(float _zMin, float _zMax);
	
	/*!
     *  \brief Récupère l'ensemble des cercles à partir du nuage de points.
	 *
     *  Remplit le tableau de cercles à partir des triplets de points trouvés dans le nuage de points de la case.
	 *
	 *  \param _tabCircles : vector de cercles à remplir.
	 *
	 *  \return : void
     */
	void getCircles(vector <Circle> & _tabCircles);

	/*!
     *  \brief Récupère l'ensemble des cercles à partir du nuage de points.
	 *
     *  Remplit directement l'espace de Hough à partir des triplets de points trouvés dans le nuage de points de la case.
	 *
	 *  \param _hs : Espace de Hough à remplir.
	 *  \param _rMax : Rayon max des cercles à chercher.
	 *
	 *  \return : void
     */
	void getCircles(HoughSpace & _hs, float _rMax);

	/*!
	 *  \brief Récupère l'ensemble des cercles à partir du nuage de points.
	 *
     *  Remplit directement l'espace de Hough à partir des triplets de points trouvés dans le nuage de points de la case en appliquant un certain coefficient.
	 *
	 *  \param _hs : Espace de Hough à remplir.
	 *  \param _rMax : Rayon max des cercles à chercher.
	 *  \param _coef : Coefficiant permettant de donner plus ou moins de poid aux cercles trouvés.
	 *
	 *  \return : void
     */
	void getCircles(HoughSpace & _hs, float _rMax, int _coef);
	
	/*!
     *  \brief Fait une coupe du nuage de points.
	 *
     *  Coupe le nuage de points de la case à partir de deux seuils.
	 *
	 *  \param _bas : Seuil bas.
	 *  \param _haut : Seuil haut.
	 *
	 *  \return : void
     */
	void keepSlice ( float _bas, float _haut );

	/*!
     *  \brief Fait une coupe du nuage de points.
	 *
     *  Coupe le nuage de points en récupérant un certain nombre de points à partir d'un seuil.
	 *
	 *  \param _bas : Seuil bas.
	 *  \param _nbPoints : Nombre de points à récupérer au dessus de l'altitude seuil.
	 *
	 *  \return : void
     */
	void keepSlice ( float _bas, int _nbPoints);
	
	/*!
     *  \brief Fait une coupe du nuage de points.
	 *
     *  Coupe le nuage de points en récupérant un certain nombre de points compris entre deux hauteurs.
	 *
	 *  \param _bas : Seuil bas.
	 *  \param _haut : Seuil haut.
	 *  \param _nbPoints : Nombre de points à récupérer au dessus de l'altitude seuil.
	 *
	 *  \return : void
     */
	void keepSlice ( float _bas, float _haut, int _nbPoints);
	
	/*!
     *  \brief Crée une coupe du nuage de points.
	 *
     *  Crée une nouvelle case contenant une coupe du nuage de points à partir de deux seuils.
	 *
	 *  \param _bas : Seuil bas.
	 *  \param _haut : Seuil haut.
	 *
	 *  \return : Nouvelle GridFrame contenant la coupe. 
     */
	GridFrame getSlice (float _bas, float _haut);
	
	/*!
     *  \brief Crée une coupe du nuage de points.
	 *
     *  Crée une nouvelle case contenant une coupe du nuage de points en récupérant un certain nombre de points à partir d'un seuil.
	 *
	 *  \param _bas : Seuil bas.
	 *  \param _nbPoints : Nombre de points à récupérer au dessus de l'altitude seuil.
	 *
	 *  \return : Nouvelle GridFrame contenant la coupe.
     */
	GridFrame getSlice ( float _bas, int _nbPoints );
	
	GridFrame getSlice ( float _bas, float _haut, int _nbPoints );
	
	/*!
     *  \brief Ecrit le point bot.
	 *
     *  Ecrit les coordonnées du point inférieur gauche de la case.
	 *
	 *  \return : void 
     */
	void printBot();
	
	/*!
     *  \brief Ecrit le point top.
	 *
     *  Ecrit les coordonnées du point supérieur droit de la case.
	 *
	 *  \return : void 
     */
	void printTop();

	/*!
	*  \brief Trie les points du nuage de la case selon leur altitude.
	*
	* \return : void
	*/
	void Sort();
};

#endif
